package com.jiamingZhao.test.cglibDemo;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * cglib动态代理演示
 * 场景：用户服务增强（日志记录 + 权限校验）
 */
public class CglibProxyDemo {

    public static void main(String[] args) {
        // 1. 创建目标对象
        UserService userService = new UserService();
        
        // 2. 创建代理对象
        UserService proxy = new UserServiceProxy().getProxyInstance(userService);
        
        // 3. 使用代理对象调用方法
        System.out.println("代理类: " + proxy.getClass());
        proxy.createUser("admin");
        proxy.deleteUser("guest");
    }
}

/**
 * 目标类（无需实现接口）
 */
class UserService {
    public void createUser(String username) {
        System.out.println("【核心业务】创建用户: " + username);
    }

    public void deleteUser(String username) {
        System.out.println("【核心业务】删除用户: " + username);
    }
}

/**
 * 方法拦截器（代理逻辑）
 */
class UserServiceProxy implements MethodInterceptor {

    /**
     * 创建代理对象
     * @param t 被代理的目标对象
     * @return 代理后的对象
     */
    public <T> T getProxyInstance(T t) {
        // 1. 创建增强器
        Enhancer enhancer = new Enhancer();
        
        // 2. 设置父类（继承方式）
        enhancer.setSuperclass(t.getClass());
        
        // 3. 设置回调（代理逻辑）
        enhancer.setCallback(this);
        
        // 4. 创建代理对象
        @SuppressWarnings("unchecked")
        T t1 = (T) enhancer.create();
        return t1;
    }

    /**
     * 拦截方法实现
     * @param obj 代理对象
     * @param method 目标方法
     * @param args 方法参数
     * @param proxy 方法代理（用于执行父类方法）
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // 1. 前置增强：日志记录
        System.out.println("[日志] 方法调用: " + method.getName() + " | 参数: " + String.join(", ", toString(args)));
        
        // 2. 前置增强：权限校验
        if ("deleteUser".equals(method.getName())) {
            System.out.println("[权限] 正在校验删除权限...");
            if (!"admin".equals(args[0])) {
                System.out.println("【拒绝】权限不足！");
                return null;
            }
        }
        
        // 3. 执行原始方法（父类方法）
        Object result = proxy.invokeSuper(obj, args);
        
        // 4. 后置增强：结果处理
        System.out.println("[日志] 方法完成: " + method.getName() + "\n");
        
        return result;
    }

    // 辅助方法：将参数数组转为字符串
    private String[] toString(Object[] arr) {
        if (arr == null) return new String[0];
        String[] result = new String[arr.length];
        for (int i = 0; i < arr.length; i++) {
            result[i] = arr[i] != null ? arr[i].toString() : "null";
        }
        return result;
    }
}